home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / other / mesa / mesa-tk / samples.tk / select.c < prev    next >
C/C++ Source or Header  |  2000-02-23  |  9KB  |  469 lines

  1. /*
  2.  * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name of
  8.  * Silicon Graphics may not be used in any advertising or
  9.  * publicity relating to the software without the specific, prior written
  10.  * permission of Silicon Graphics.
  11.  *
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
  13.  * ANY KIND,
  14.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16.  *
  17.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
  18.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  21.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22.  * OF THIS SOFTWARE.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <math.h>
  28. #include <string.h>
  29. #include <time.h>
  30. #include "gltk.h"
  31.  
  32. #define MAXOBJS 10000
  33. #define MAXSELECT 100
  34. #define MAXFEED 300
  35. #define    SOLID 1
  36. #define    LINE 2
  37. #define    POINT 3
  38.  
  39. GLenum directRender;
  40. GLint windW, windH;
  41.  
  42. GLuint selectBuf[MAXSELECT];
  43. GLfloat feedBuf[MAXFEED];
  44. GLint vp[4];
  45. float zRotation = 90.0;
  46. float zoom = 1.0;
  47. GLint objectCount;
  48. GLint numObjects;
  49. struct object {
  50.   float v1[2];
  51.   float v2[2];
  52.   float v3[2];
  53.   float color[3];
  54. } objects[MAXOBJS];
  55. GLenum linePoly = GL_FALSE;
  56.  
  57. static void InitObjects(GLint num)
  58. {
  59.   GLint i;
  60.   float x, y;
  61.  
  62.   if (num > MAXOBJS) {
  63.     num = MAXOBJS;
  64.   }
  65.   if (num < 1) {
  66.     num = 1;
  67.   }
  68.   objectCount = num;
  69.  
  70.   srand((unsigned int)time(NULL));
  71.   for (i = 0; i < num; i++) {
  72.     x = (rand() % 300) - 150;
  73.     y = (rand() % 300) - 150;
  74.  
  75.     objects[i].v1[0] = x + (rand() % 50) - 25;
  76.     objects[i].v2[0] = x + (rand() % 50) - 25;
  77.     objects[i].v3[0] = x + (rand() % 50) - 25;
  78.     objects[i].v1[1] = y + (rand() % 50) - 25;
  79.     objects[i].v2[1] = y + (rand() % 50) - 25;
  80.     objects[i].v3[1] = y + (rand() % 50) - 25;
  81.     objects[i].color[0] = ((rand() % 100) + 50) / 150.0;
  82.     objects[i].color[1] = ((rand() % 100) + 50) / 150.0;
  83.     objects[i].color[2] = ((rand() % 100) + 50) / 150.0;
  84.   }
  85. }
  86.  
  87. static void Init(void)
  88. {
  89.  
  90.   numObjects = 10;
  91.   InitObjects(numObjects);
  92.   glGetIntegerv(GL_VIEWPORT, vp);
  93. }
  94.  
  95. static void Reshape(int width, int height)
  96. {
  97.  
  98.   windW = (GLint) width;
  99.   windH = (GLint) height;
  100. }
  101.  
  102. static void Render(GLenum mode)
  103. {
  104.   GLint i;
  105.  
  106.   for (i = 0; i < objectCount; i++) {
  107.     if (mode == GL_SELECT) {
  108.       glLoadName(i);
  109.     }
  110.     glColor3fv(objects[i].color);
  111.     glBegin(GL_POLYGON);
  112.     glVertex2fv(objects[i].v1);
  113.     glVertex2fv(objects[i].v2);
  114.     glVertex2fv(objects[i].v3);
  115.     glEnd();
  116.   }
  117. }
  118.  
  119. static GLint DoSelect(GLint x, GLint y)
  120. {
  121.   GLint hits;
  122.  
  123.   glSelectBuffer(MAXSELECT, selectBuf);
  124.   (void)glRenderMode(GL_SELECT);
  125.   glInitNames();
  126.   glPushName(~0);
  127.  
  128.   glPushMatrix();
  129.  
  130.   glViewport(0, 0, windW, windH);
  131.   glGetIntegerv(GL_VIEWPORT, vp);
  132.  
  133.   glMatrixMode(GL_PROJECTION);
  134.   glLoadIdentity();
  135.   gluPickMatrix(x, windH - y, 4, 4, vp);
  136.   gluOrtho2D(-175, 175, -175, 175);
  137.   glMatrixMode(GL_MODELVIEW);
  138.  
  139.   glClearColor(0.0, 0.0, 0.0, 0.0);
  140.   glClear(GL_COLOR_BUFFER_BIT);
  141.  
  142.   glScalef(zoom, zoom, zoom);
  143.   glRotatef(zRotation, 0, 0, 1);
  144.  
  145.   Render(GL_SELECT);
  146.  
  147.   glPopMatrix();
  148.  
  149.   hits = glRenderMode(GL_RENDER);
  150.   if (hits <= 0) {
  151.     return -1;
  152.   }
  153.  
  154.   return selectBuf[(hits - 1) * 4 + 3];
  155. }
  156.  
  157. static void RecolorTri(GLint h)
  158. {
  159.  
  160.   objects[h].color[0] = ((rand() % 100) + 50) / 150.0;
  161.   objects[h].color[1] = ((rand() % 100) + 50) / 150.0;
  162.   objects[h].color[2] = ((rand() % 100) + 50) / 150.0;
  163. }
  164.  
  165. static void DeleteTri(GLint h)
  166. {
  167.  
  168.   objects[h] = objects[objectCount - 1];
  169.   objectCount--;
  170. }
  171.  
  172. static void GrowTri(GLint h)
  173. {
  174.   float v[2];
  175.   float *oldV;
  176.   GLint i;
  177.  
  178.   v[0] = objects[h].v1[0] + objects[h].v2[0] + objects[h].v3[0];
  179.   v[1] = objects[h].v1[1] + objects[h].v2[1] + objects[h].v3[1];
  180.   v[0] /= 3;
  181.   v[1] /= 3;
  182.  
  183.   for (i = 0; i < 3; i++) {
  184.     switch (i) {
  185.       case 0:
  186.     oldV = objects[h].v1;
  187.     break;
  188.       case 1:
  189.     oldV = objects[h].v2;
  190.     break;
  191.       case 2:
  192.     oldV = objects[h].v3;
  193.     break;
  194.     }
  195.     oldV[0] = 1.5 * (oldV[0] - v[0]) + v[0];
  196.     oldV[1] = 1.5 * (oldV[1] - v[1]) + v[1];
  197.   }
  198. }
  199.  
  200. static GLenum Mouse(int mouseX, int mouseY, GLenum button)
  201. {
  202.   GLint hit;
  203.  
  204.   hit = DoSelect((GLint) mouseX, (GLint) mouseY);
  205.   if (hit != -1) {
  206.     if (button & TK_LEFTBUTTON) {
  207.       RecolorTri(hit);
  208.     }
  209.     if (button & TK_MIDDLEBUTTON) {
  210.       GrowTri(hit);
  211.     }
  212.     if (button & TK_RIGHTBUTTON) {
  213.       DeleteTri(hit);
  214.     }
  215.     return GL_TRUE;
  216.   }
  217.   return GL_FALSE;
  218. }
  219.  
  220. static void Draw(void)
  221. {
  222.  
  223.   glPushMatrix();
  224.  
  225.   glViewport(0, 0, windW, windH);
  226.   glGetIntegerv(GL_VIEWPORT, vp);
  227.  
  228.   glMatrixMode(GL_PROJECTION);
  229.   glLoadIdentity();
  230.   gluOrtho2D(-175, 175, -175, 175);
  231.   glMatrixMode(GL_MODELVIEW);
  232.  
  233.   glClearColor(0.0, 0.0, 0.0, 0.0);
  234.   glClear(GL_COLOR_BUFFER_BIT);
  235.  
  236.   glScalef(zoom, zoom, zoom);
  237.   glRotatef(zRotation, 0, 0, 1);
  238.  
  239.   Render(GL_RENDER);
  240.  
  241.   glPopMatrix();
  242.  
  243.   glFlush();
  244. }
  245.  
  246. static void DrawZoom(GLint x, GLint y)
  247. {
  248.  
  249.   glPushMatrix();
  250.  
  251.   glViewport(0, 0, windW, windH);
  252.   glGetIntegerv(GL_VIEWPORT, vp);
  253.  
  254.   glMatrixMode(GL_PROJECTION);
  255.   glLoadIdentity();
  256.   gluPickMatrix(x, windH - y, 4, 4, vp);
  257.   gluOrtho2D(-175, 175, -175, 175);
  258.   glMatrixMode(GL_MODELVIEW);
  259.  
  260.   glClearColor(0.0, 0.0, 0.0, 0.0);
  261.   glClear(GL_COLOR_BUFFER_BIT);
  262.  
  263.   glScalef(zoom, zoom, zoom);
  264.   glRotatef(zRotation, 0, 0, 1);
  265.  
  266.   Render(GL_RENDER);
  267.  
  268.   glPopMatrix();
  269. }
  270.  
  271. static void DumpFeedbackVert(GLint * i, GLint n)
  272. {
  273.   GLint index;
  274.  
  275.   index = *i;
  276.   if (index + 7 > n) {
  277.     *i = n;
  278.     printf("  ???\n");
  279.     return;
  280.   }
  281.   printf("  (%g %g %g), color = (%4.2f %4.2f %4.2f)\n",
  282.      feedBuf[index],
  283.      feedBuf[index + 1],
  284.      feedBuf[index + 2],
  285.      feedBuf[index + 3],
  286.      feedBuf[index + 4],
  287.      feedBuf[index + 5]);
  288.   index += 7;
  289.   *i = index;
  290. }
  291.  
  292. static void DrawFeedback(GLint n)
  293. {
  294.   GLint i;
  295.   GLint verts;
  296.  
  297.   printf("Feedback results (%d floats):\n", n);
  298.   for (i = 0; i < n; i++) {
  299.     switch ((GLint) feedBuf[i]) {
  300.       case GL_POLYGON_TOKEN:
  301.     printf("Polygon");
  302.     i++;
  303.     if (i < n) {
  304.       verts = (GLint) feedBuf[i];
  305.       i++;
  306.       printf(": %d vertices", verts);
  307.     }
  308.     else {
  309.       verts = 0;
  310.     }
  311.     printf("\n");
  312.     while (verts) {
  313.       DumpFeedbackVert(&i, n);
  314.       verts--;
  315.     }
  316.     i--;
  317.     break;
  318.       case GL_LINE_TOKEN:
  319.     printf("Line:\n");
  320.     i++;
  321.     DumpFeedbackVert(&i, n);
  322.     DumpFeedbackVert(&i, n);
  323.     i--;
  324.     break;
  325.       case GL_LINE_RESET_TOKEN:
  326.     printf("Line Reset:\n");
  327.     i++;
  328.     DumpFeedbackVert(&i, n);
  329.     DumpFeedbackVert(&i, n);
  330.     i--;
  331.     break;
  332.       default:
  333.     printf("%9.2f\n", feedBuf[i]);
  334.     break;
  335.     }
  336.   }
  337.   if (i == MAXFEED) {
  338.     printf("...\n");
  339.   }
  340.   printf("\n");
  341. }
  342.  
  343. static void DoFeedback(void)
  344. {
  345.   GLint x;
  346.  
  347.   glFeedbackBuffer(MAXFEED, GL_3D_COLOR, feedBuf);
  348.   (void)glRenderMode(GL_FEEDBACK);
  349.  
  350.   glPushMatrix();
  351.  
  352.   glViewport(0, 0, windW, windH);
  353.   glGetIntegerv(GL_VIEWPORT, vp);
  354.  
  355.   glMatrixMode(GL_PROJECTION);
  356.   glLoadIdentity();
  357.   gluOrtho2D(-175, 175, -175, 175);
  358.   glMatrixMode(GL_MODELVIEW);
  359.  
  360.   glClearColor(0.0, 0.0, 0.0, 0.0);
  361.   glClear(GL_COLOR_BUFFER_BIT);
  362.  
  363.   glScalef(zoom, zoom, zoom);
  364.   glRotatef(zRotation, 0, 0, 1);
  365.  
  366.   Render(GL_FEEDBACK);
  367.  
  368.   glPopMatrix();
  369.  
  370.   x = glRenderMode(GL_RENDER);
  371.   if (x == -1) {
  372.     x = MAXFEED;
  373.   }
  374.  
  375.   DrawFeedback((GLint) x);
  376. }
  377.  
  378. static GLenum Key(int key, GLenum mask)
  379. {
  380.   int mouseX, mouseY;
  381.  
  382.   switch (key) {
  383.     case TK_ESCAPE:
  384.       tkQuit();
  385.     case TK_LEFT:
  386.       zRotation += 0.5;
  387.       break;
  388.     case TK_RIGHT:
  389.       zRotation -= 0.5;
  390.       break;
  391.     case TK_Z:
  392.       zoom /= 0.75;
  393.       break;
  394.     case TK_z:
  395.       zoom *= 0.75;
  396.       break;
  397.     case TK_f:
  398.       DoFeedback();
  399.       break;
  400.     case TK_d:
  401.       tkGetMouseLoc(&mouseX, &mouseY);
  402.       DrawZoom((GLint) mouseX, (GLint) mouseY);
  403.       break;
  404.     case TK_l:
  405.       linePoly = !linePoly;
  406.       if (linePoly) {
  407.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  408.       }
  409.       else {
  410.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  411.       }
  412.       break;
  413.     default:
  414.       return GL_FALSE;
  415.   }
  416.   return GL_TRUE;
  417. }
  418.  
  419. static GLenum Args(int argc, char **argv)
  420. {
  421.   GLint i;
  422.  
  423.   directRender = GL_TRUE;
  424.  
  425.   for (i = 1; i < argc; i++) {
  426.     if (strcmp(argv[i], "-dr") == 0) {
  427.       directRender = GL_TRUE;
  428.     }
  429.     else if (strcmp(argv[i], "-ir") == 0) {
  430.       directRender = GL_FALSE;
  431.     }
  432.     else {
  433.       printf("%s (Bad option).\n", argv[i]);
  434.       return GL_FALSE;
  435.     }
  436.   }
  437.   return GL_TRUE;
  438. }
  439.  
  440. void main(int argc, char **argv)
  441. {
  442.   GLenum type;
  443.  
  444.   if (Args(argc, argv) == GL_FALSE) {
  445.     tkQuit();
  446.   }
  447.  
  448.   windW = 300;
  449.   windH = 300;
  450.   tkInitPosition(0, 0, windW, windH);
  451.  
  452.   type = TK_RGB | TK_SINGLE;
  453.   type |= (directRender) ? TK_DIRECT : TK_INDIRECT;
  454.   tkInitDisplayMode(type);
  455.  
  456.   if (tkInitWindow("Select Test") == GL_FALSE) {
  457.     tkQuit();
  458.   }
  459.  
  460.   Init();
  461.  
  462.   tkExposeFunc(Reshape);
  463.   tkReshapeFunc(Reshape);
  464.   tkKeyDownFunc(Key);
  465.   tkMouseDownFunc(Mouse);
  466.   tkDisplayFunc(Draw);
  467.   tkExec();
  468. }
  469.